home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / Spiele / GEMSPIEL / SOLITARE.11A / SOURCE / LIBS / IMAGE.C < prev    next >
Encoding:
Text File  |  1999-12-13  |  10.9 KB  |  547 lines

  1. /*
  2.     image.c
  3.  
  4.         bibliothek zum laden von gem-ximage-dateien
  5.  
  6.  
  7.         FEHLER: bei monochromen bitmaps wird identität von geräte und standardformat angenommen!!!
  8.  
  9.  
  10.     geschrieben von Th. Morus Walter
  11.  
  12.     (c) 1994/95 by Th. Morus Walter
  13. */
  14. #include <tos.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #include <image.h>
  19.  
  20. /*
  21.     int load_ximg(char *name,MFDB *mfdb,IMG_COLOR **coltab)
  22.     int load_img(char *name,MFDB *mfdb)
  23.  
  24. lade gem-image datei
  25.  
  26. rückgabewerte
  27.     0  -> ok
  28.     <0 -> os-error
  29.     >0 -> 3: format falsch
  30.        -> 2: speicher reicht nicht
  31.        -> 1: allg error
  32.  
  33. coltab wird auf 0l gesetzt wenn keine XIMG datei geladen wird
  34. speicher für bilddaten und farbtabelle wird mit malloc alloziert
  35.  
  36.     changes:
  37.         ⓪⑤.⓪①.①⑨⑨⑤  setze picture->fd_r1..fd_r3 auf 0
  38.         ②⑧.⓪③.①⑨⑨⑤    größerer puffer via malloc
  39.                         falls nicht möglich -> kleiner (256) buffer auf stack
  40. */
  41.  
  42. #define BUF_SIZE        16384
  43. #define NOT_BUF_SIZE    256
  44.  
  45. static long buf_size;
  46. static int f_id;
  47. static char *w_buf;
  48. static int z,z1;
  49. static long l;
  50.  
  51. static int init_get_byte(long len,char *not_puffer)
  52. {
  53.     l=len;
  54.     z=0;
  55.     buf_size=BUF_SIZE;
  56.     w_buf=malloc(BUF_SIZE);
  57.     if ( !w_buf ) {
  58.         w_buf=not_puffer;
  59.         buf_size=NOT_BUF_SIZE;
  60.     }
  61.     return IMG_OK;
  62. }
  63.  
  64. static int get_byte(char *byte)
  65. {
  66. long len;
  67. long ret;
  68.  
  69.     if ( z==0 ) {
  70.         if ( l<buf_size ) {
  71.             len=l;
  72.         }
  73.         else {
  74.             len=buf_size;
  75.             l-=buf_size;
  76.         }
  77.         if ( (ret=Fread(f_id,len,w_buf))!=len ) {
  78.             if ( ret<0 )
  79.                 return (int)ret;
  80.             else
  81.                 return IMG_ERROR;
  82.         }
  83.         z=(int)len;
  84.         z1=0;
  85.     }
  86.     *byte=w_buf[z1];
  87.     z1++;
  88.     z--;
  89.     return IMG_OK;
  90. }
  91.  
  92. static int get_block(char *buf,int len)
  93. {
  94. int ret;
  95.  
  96.     for ( ; len>0; len-- )
  97.         if ( (ret=get_byte(buf++))!=IMG_OK )
  98.             return ret;
  99.     return IMG_OK;
  100. }
  101.  
  102. static int do_ld_img(char *buffer,char *line_buf,IMG_HEADER *head)
  103. {                /* return: <0 -> os-error, IMG_FORMAT falsches datenformat, IMG_ERROR tosfehler, 0 ok */
  104. char *line,*h,*h1;
  105. char byte,l_cnt,b_cnt;
  106. char muster[16];
  107. int lline_len,line_len;
  108. long pl_len;
  109. int planes,lines,bytes,i;
  110.  
  111.     line_len=head->pix_num/8;
  112.     if ( head->pix_num%8 )
  113.         line_len++;
  114.     lline_len=line_len*head->plane_num;
  115.     pl_len=(long)line_len*head->scan_num;
  116.     if ( line_len&1 )
  117.         pl_len+=head->scan_num;
  118.  
  119.     line=buffer;
  120.     h=line_buf;
  121.     bytes=lines=0;
  122.     l_cnt=1;        /* anzahl von zeilenwiederholungen */
  123.  
  124.     while (1) {
  125.         if ( bytes>=lline_len ) {    /* ganze zeile eingelesen */
  126.             for ( ; l_cnt>0; l_cnt-- ) {
  127.                 h1=line_buf;
  128.                 for ( planes=0; planes<head->plane_num; planes++ ) {
  129.                     for ( i=0,h=line+planes*pl_len; i<line_len; i++ )
  130.                         *h++=*h1++;
  131.                     if ( line_len&1 )
  132.                         *h++=0;
  133.                 }
  134.                 lines++;
  135.                 line+=line_len;
  136.                 if ( line_len&1 )
  137.                     line++;
  138.             }
  139.             if ( lines>=head->scan_num )
  140.                 return IMG_OK;
  141.             l_cnt=1;
  142.             h=line_buf;
  143.             bytes=0;
  144.         }
  145.  
  146.         if ( get_byte(&byte)!=IMG_OK )
  147.             return IMG_ERROR;
  148.         if ( byte==0 ) {
  149.             if ( get_byte(&byte)!=IMG_OK )
  150.                 return IMG_ERROR;
  151.             if ( byte==0 ) {
  152.                 if ( get_byte(&byte)!=IMG_OK )
  153.                     return IMG_ERROR;
  154.                 if ( byte!=0xFF )
  155.                     return IMG_FORMAT;
  156.                 if ( get_byte(&l_cnt)!=IMG_OK )
  157.                     return IMG_ERROR;
  158.             }
  159.             else {
  160.                 for ( i=0; i<head->pat_len; i++ )
  161.                     if ( get_byte(muster+i)!=IMG_OK )
  162.                         return IMG_ERROR;
  163.                 for ( ; byte>0; byte-- ) {
  164.                     for ( i=0; i<head->pat_len; i++ ) {
  165.                         *h++=muster[i];
  166.                         bytes++;
  167.                         if ( bytes>lline_len )
  168.                             return IMG_FORMAT;
  169.                     }
  170.                 }
  171.             }
  172.         }
  173.         else if ( byte==0x80 ) {
  174.             if ( get_byte(&b_cnt)!=IMG_OK )
  175.                 return IMG_ERROR;
  176.             for ( ; b_cnt>0; b_cnt-- ) {
  177.                 if ( get_byte(h++)!=IMG_OK )
  178.                     return IMG_ERROR;
  179.                 bytes++;
  180.                 if ( bytes>lline_len )
  181.                     return IMG_FORMAT;
  182.             }
  183.         }
  184.         else {
  185.           int set=0;
  186.             if ( byte&0x80 ) {
  187.                 byte&=0x7F;
  188.                 set=0xFF;
  189.             }
  190.             for ( ; byte>0; byte-- ) {
  191.                 *h++=set;
  192.                 bytes++;
  193.                 if ( bytes>lline_len )
  194.                     return IMG_FORMAT;
  195.             }
  196.         }
  197.     }
  198. }
  199.  
  200. static IMG_ERR do_load_ximg(IMG_HEADER *head,char *name,MFDB *picture,IMG_COLOR **coltab)
  201. {
  202. long len,llen;
  203. int line_len;
  204. IMG_ERR ret;
  205. char *line_buf;
  206. char byte;
  207. char not_puffer[NOT_BUF_SIZE];
  208.  
  209.     picture->fd_addr=0l;
  210.  
  211.     f_id=Fopen(name,0);
  212.     if ( f_id<0 )
  213.         return f_id;
  214.  
  215.     if ( (len=Fseek(0,f_id,2))<0 ) {
  216.         Fclose(f_id);
  217.         return (int)len;
  218.     }
  219.     if ( Fseek(0,f_id,0)!=0l ) {
  220.         Fclose(f_id);
  221.         return IMG_ERROR;
  222.     }
  223.  
  224.     if ( init_get_byte(len,not_puffer)!=IMG_OK )
  225.         return IMG_MEMORY;
  226.  
  227.     /*
  228.             lese header
  229.     */
  230.     if ( (ret=get_block((char*)head,(int)sizeof(IMG_HEADER)))!=IMG_OK ) {
  231.         Fclose(f_id);
  232.         return ret;
  233.     }
  234.  
  235.     head->head_len*=2;    /* head_len in bytes, nicht words */
  236.     len-=head->head_len;
  237.     head->head_len-=(int)sizeof(IMG_HEADER);
  238.  
  239.     *coltab=0l;
  240.     if ( head->head_len>sizeof(IMG_HEADER) ) {        /* zus. header überlesen */
  241.       struct {                                    /* ximg-header lesen */
  242.         long id;
  243.         int col_flag;
  244.       } ximg;
  245.       int col_len;
  246.  
  247.         if ( head->head_len>sizeof(ximg) ) {
  248.             if ( get_block((char*)&ximg,(int)sizeof(ximg))!=IMG_OK ) {
  249.                 Fclose(f_id);
  250.                 return IMG_ERROR;
  251.             }
  252.             head->head_len-=(int)sizeof(ximg);
  253.             if ( ximg.id=='XIMG' && ximg.col_flag==0 ) {
  254.                 col_len=(int)sizeof(IMG_COLOR)*1<<head->plane_num;
  255.                 *coltab=malloc(col_len);
  256.                 if ( *coltab==0l ) {
  257.                     Fclose(f_id);
  258.                     return IMG_MEMORY;
  259.                 }
  260.                 if ( col_len<=head->head_len ) {
  261.                     if ( get_block((char*)*coltab,col_len)!=IMG_OK ) {
  262.                         Fclose(f_id);
  263.                         return IMG_ERROR;
  264.                     }
  265.                     head->head_len-=(int)col_len;
  266.                 }
  267.                 else {
  268.                     free(*coltab);
  269.                 }
  270.             }
  271.         }
  272.     }
  273.  
  274.     if ( head->head_len>0 ) {
  275.         while ( head->head_len-- ) {
  276.             if ( (ret=get_byte(&byte))!=IMG_OK ) {
  277.                 Fclose(f_id);
  278.                 return ret;
  279.             }
  280.         }
  281.     }
  282.     else if ( head->head_len<0 ) {
  283.         Fclose(f_id);
  284.         return IMG_FORMAT;
  285.     }
  286.  
  287.     if ( head->plane_num>8 || head->pat_len>8 ) {
  288.         Fclose(f_id);
  289.         return IMG_FORMAT;
  290.     }
  291.  
  292.     picture->fd_h=head->scan_num;
  293.     picture->fd_nplanes=head->plane_num;
  294.     picture->fd_stand=1;
  295.     picture->fd_r1=picture->fd_r2=picture->fd_r3=0;
  296.  
  297.     line_len=head->pix_num/8;
  298.     if ( head->pix_num%8 )
  299.         line_len++;
  300.     picture->fd_wdwidth=line_len/2;
  301.     if ( line_len&1 )
  302.         picture->fd_wdwidth++;
  303.     
  304.     picture->fd_w=head->pix_num;
  305.  
  306.     len=(long)picture->fd_wdwidth*2*(long)head->scan_num*(long)head->plane_num;
  307.  
  308.     picture->fd_addr=malloc(len);
  309.     if ( picture->fd_addr==0l ) {
  310.         Fclose(f_id);
  311.         return IMG_MEMORY;
  312.     }
  313.  
  314.     llen=(long)head->pix_num*head->plane_num/8;
  315.     line_buf=malloc(llen);
  316.     if ( !line_buf ) {
  317.         Fclose(f_id);
  318.         return IMG_MEMORY;
  319.     }
  320.  
  321.     ret=do_ld_img(picture->fd_addr,line_buf,head);
  322.  
  323.     Fclose(f_id);
  324.     free(line_buf);
  325.     free(w_buf);
  326.  
  327.     return ret;
  328. }
  329.  
  330.  
  331. static IMG_ERR do_load_img(IMG_HEADER *head,char *name,MFDB *picture)
  332. {
  333. long len,llen;
  334. int line_len;
  335. IMG_ERR ret;
  336. char *line_buf;
  337. char byte;
  338. char not_puffer[NOT_BUF_SIZE];
  339.  
  340.     picture->fd_addr=0l;
  341.  
  342.     f_id=Fopen(name,0);
  343.     if ( f_id<0 )
  344.         return f_id;
  345.  
  346.     if ( (len=Fseek(0,f_id,2))<0 ) {
  347.         Fclose(f_id);
  348.         return (int)len;
  349.     }
  350.     if ( Fseek(0,f_id,0)!=0l ) {
  351.         Fclose(f_id);
  352.         return IMG_ERROR;
  353.     }
  354.  
  355.     if ( init_get_byte(len,not_puffer)!=IMG_OK )
  356.         return IMG_MEMORY;
  357.  
  358.     /*
  359.             lese header
  360.     */
  361.     if ( (ret=get_block((char*)head,(int)sizeof(IMG_HEADER)))!=IMG_OK ) {
  362.         Fclose(f_id);
  363.         return ret;
  364.     }
  365.  
  366.     head->head_len*=2;    /* head_len in bytes, nicht words */
  367.     len-=head->head_len;
  368.     head->head_len-=(int)sizeof(IMG_HEADER);
  369.  
  370.     if ( head->head_len>0 ) {
  371.         while ( head->head_len-- ) {
  372.             if ( (ret=get_byte(&byte))!=IMG_OK ) {
  373.                 Fclose(f_id);
  374.                 return ret;
  375.             }
  376.         }
  377.     }
  378.     else if ( head->head_len<0 ) {
  379.         Fclose(f_id);
  380.         return IMG_FORMAT;
  381.     }
  382.  
  383.     if ( head->plane_num>8 || head->pat_len>8 ) {
  384.         Fclose(f_id);
  385.         return IMG_FORMAT;
  386.     }
  387.  
  388.     picture->fd_h=head->scan_num;
  389.     picture->fd_nplanes=head->plane_num;
  390.     picture->fd_stand=1;
  391.     picture->fd_r1=picture->fd_r2=picture->fd_r3=0;
  392.  
  393.     line_len=head->pix_num/8;
  394.     if ( head->pix_num%8 )
  395.         line_len++;
  396.     picture->fd_wdwidth=line_len/2;
  397.     if ( line_len&1 )
  398.         picture->fd_wdwidth++;
  399.     
  400.     picture->fd_w=head->pix_num;
  401.  
  402.     len=(long)picture->fd_wdwidth*2*(long)head->scan_num*(long)head->plane_num;
  403.  
  404.     picture->fd_addr=malloc(len);
  405.     if ( picture->fd_addr==0l ) {
  406.         Fclose(f_id);
  407.         return IMG_MEMORY;
  408.     }
  409.  
  410.     llen=(long)head->pix_num*head->plane_num/8;
  411.     line_buf=malloc(llen);
  412.     if ( !line_buf ) {
  413.         Fclose(f_id);
  414.         return IMG_MEMORY;
  415.     }
  416.  
  417.     ret=do_ld_img(picture->fd_addr,line_buf,head);
  418.  
  419.     Fclose(f_id);
  420.     free(line_buf);
  421.     free(w_buf);
  422.  
  423.     return ret;
  424. }
  425.  
  426.  
  427. IMG_ERR xload_ximg(IMG_HEADER *head,char *name,MFDB *picture,IMG_COLOR **coltab)
  428. {
  429. IMG_ERR ret;
  430.  
  431.     ret=do_load_ximg(head,name,picture,coltab);
  432.     if ( ret!=IMG_OK ) {
  433.         if ( picture->fd_addr ) {
  434.             free(picture->fd_addr);
  435.             picture->fd_addr=0l;
  436.         }
  437.         if ( *coltab ) {
  438.             free(*coltab);
  439.             *coltab=0l;
  440.         }
  441.         if ( w_buf )
  442.             free(w_buf);
  443.     }
  444.     return ret;
  445. }
  446.  
  447. IMG_ERR xload_img(IMG_HEADER *head,char *name,MFDB *picture)
  448. {
  449. IMG_ERR ret;
  450.  
  451.     ret=do_load_img(head,name,picture);
  452.     if ( ret!=IMG_OK ) {
  453.         if ( picture->fd_addr ) {
  454.             free(picture->fd_addr);
  455.             picture->fd_addr=0l;
  456.         }
  457.         if ( w_buf )
  458.             free(w_buf);
  459.     }
  460.     return ret;
  461. }
  462.  
  463. IMG_ERR load_ximg(char *name,MFDB *picture,IMG_COLOR **coltab)
  464. {
  465. IMG_HEADER head;
  466.  
  467.     return xload_ximg(&head,name,picture,coltab);
  468. }
  469.  
  470. IMG_ERR load_img(char *name,MFDB *picture)
  471. {
  472. IMG_HEADER head;
  473.  
  474.     return xload_img(&head,name,picture);
  475. }
  476.  
  477.  
  478. TRFM_ERR transform_img(MFDB *pic,int planes,int vdi_handle)
  479.                     /* pic ist in&out-parameter */
  480.                     /* in: std-format, bel. zahl von planes */
  481.                     /* out: device-format, planes */
  482.             /* return: 0 -> error (out of mem), 1 -> ok */
  483. {
  484. MFDB p;
  485. long pic_len;
  486.  
  487.     if ( pic->fd_nplanes>planes )        /* zu viele planes geht nicht! */
  488.         return TRFM_ERROR;
  489.  
  490.     if ( pic->fd_nplanes==1 && planes==1 ) {
  491.         pic->fd_stand=0;                /* hmm, this is a hack!!! */
  492.         return TRFM_OK;
  493.     }
  494.  
  495.                                         /* länge der zielbitmap */
  496.     pic_len=(long)pic->fd_wdwidth*2l*(long)pic->fd_h*(long)planes;
  497.     p=*pic;
  498.  
  499.                                         /* speicher holen */
  500.     p.fd_addr=malloc(pic_len);
  501.     if ( !p.fd_addr )
  502.         return TRFM_MEMORY;
  503.  
  504.     if ( pic->fd_nplanes==1 && planes>1 ) {
  505.       int xy[8],col[2];
  506.                                         /* spezialfall: eine plane auf mehrere abbilden */
  507.         pic->fd_stand=0;                /* hmm, this is a hack!!! */
  508.         p.fd_stand=0;
  509.  
  510.         xy[0]=xy[4]=xy[1]=xy[5]=0;
  511.         xy[2]=xy[6]=pic->fd_w-1;
  512.         xy[3]=xy[7]=pic->fd_h-1;
  513.         col[0]=1;
  514.         col[1]=0;
  515.         vrt_cpyfm(vdi_handle,MD_REPLACE,xy,pic,&p,col);
  516.         free(pic->fd_addr);
  517.         *pic=p;
  518.         return TRFM_OK;
  519.     }
  520.  
  521.                                         /* quelle hat zuwenig planes -> 0planes anhängen */
  522.     if ( pic->fd_nplanes<planes ) {
  523.       MFDB pp;
  524.           pp=*pic;
  525.           pp.fd_addr=malloc(pic_len);
  526.           if ( !pp.fd_addr )
  527.               { free(p.fd_addr); return TRFM_MEMORY; }
  528.         pp.fd_nplanes=planes;
  529.  
  530.         memset(pp.fd_addr,0,pic_len);    /*    -> fülle mit 0-planes */
  531.           memcpy(pp.fd_addr,pic->fd_addr,(long)pic->fd_wdwidth*2l*(long)pic->fd_h*(long)pic->fd_nplanes);
  532.         free(pic->fd_addr);
  533.         *pic=pp;
  534.     }
  535.  
  536.     p.fd_stand=0;                        /* transformieren */
  537.     vr_trnfm(vdi_handle,pic,&p);
  538.  
  539.     free(pic->fd_addr);
  540.  
  541.     *pic=p;
  542.     pic->fd_nplanes=planes;
  543.  
  544.     return TRFM_OK;
  545. }
  546.  
  547.